package com.jy.api.pay.request;

import com.jy.api.domain.Order;
import com.jy.api.util.SignUtil;
import com.jy.api.util.SignUtils;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.Map;

/**
 * Created by lihu on 2017/10/9.
 * 威副通支付请求实体
 */
@Data
@XStreamAlias("xml")
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class PayRequest {


    @XStreamAlias("sign")
    private String sign;

    @XStreamAlias("nonce_str")
    private String nonce_str = String.valueOf(new Date().getTime());

    //接口类型
    @XStreamAlias("service")
    private String service;

    //商户号
    @XStreamAlias("mch_id")
    private String mch_id;

    //商户订单号
    @XStreamAlias("out_trade_no")
    private String out_trade_no;

    //商品信息
    @XStreamAlias("body")
    private String body;

    //总金额
    @XStreamAlias("total_fee")
    private int total_fee;

    // 终端ip
    @XStreamAlias("mch_create_ip")
    private String mch_create_ip;

    @XStreamAlias("bill_type")
    private String bill_type;

    //通知地址
    @XStreamAlias("notify_url")
    private String notify_url;

    //获取用户的openid
    @XStreamAlias("sub_openid")
    private String sub_openid;

    //商户的微信公众号ID
    @XStreamAlias("sub_appid")
    private String sub_appid;


    //授权码
    @XStreamAlias("auth_code")
    private String auth_code;

    //是否原生
    @XStreamAlias("is_raw")
    private int is_raw;

    //附加信息
    @XStreamAlias("attach")
    private String attach;

    //退单号
    @XStreamAlias("out_refund_no")
    private String out_refund_no;

    //总金额
    @XStreamAlias("refund_fee")
    private int refund_fee;

    //总金额
    @XStreamAlias("op_user_id")
    private String op_user_id;

    //总金额
    @XStreamAlias("transaction_id")
    private String transaction_id;

    @XStreamAlias("sign_type")
    private String sign_type;

    // 终端设备号，商户自定义。特别说明：对于QQ钱包支付，此参数必传，否则会报错
    @XStreamAlias("device_info")
    private String device_info;
    //渠道编号
    @XStreamAlias("sign_agentno")
    private String sign_agentno;

    @XStreamAlias("bill_date")
    private String bill_date;

    public PayRequest(String service, String mch_id, String outTradeNo) {
        this.service = service;
        this.mch_id = mch_id;
        this.out_trade_no = outTradeNo;
        this.sign_agentno = "10100000284";

    }

    public PayRequest(String service, String outTradeNo, String mchCreateIp,
                      String notifyUrl, int amount) throws Exception {
        this.service = service;
        this.mch_id = "399520227696";
        this.out_trade_no = outTradeNo;
        this.body = "店铺充值";
        this.total_fee = amount;
        this.mch_create_ip = mchCreateIp;
        this.notify_url = notifyUrl;
        this.sign_agentno = "10100000284";
    }


    public PayRequest(String service, String mchId, String outTradeNo,
                      String body,
                      int totalFee, String mchCreateIp,
                      String notifyUrl) {
        this.service = service;
        this.mch_id = mchId;
        this.out_trade_no = outTradeNo;
        this.body = body;
        this.total_fee = totalFee;
        this.mch_create_ip = mchCreateIp;
        this.notify_url = notifyUrl;
        this.sign_agentno="10100000284";
    }


    public PayRequest(String service, String mch_id, String out_trade_no, String body,
                      String sub_openid, String sub_appid, int total_fee,
                      String mch_create_ip, String notify_url) {
        this.is_raw = 1;
        this.service = service;
        this.mch_id = mch_id;
        this.out_trade_no = out_trade_no;
        this.body = body;
        this.sub_openid = sub_openid;
        this.sub_appid = sub_appid;
        this.total_fee = total_fee;
        this.mch_create_ip = mch_create_ip;
        this.notify_url = notify_url;
        this.sign_agentno = "10100000284";
    }

    /**
     * 退款的参数构建
     *
     * @param service
     * @param mch_id
     * @param out_trade_no
     * @param out_refund_no
     * @param total_fee
     * @param refund_fee
     * @param op_user_id
     */
    public PayRequest(String service, String mch_id, String out_trade_no, String out_refund_no,
                      int total_fee, int refund_fee, String op_user_id
    ) {
        //接口类型
        this.service = service;
        //商户号
        this.mch_id = mch_id;
        //商户订单号
        this.out_trade_no = out_trade_no;
        //商户退款单号
        this.out_refund_no = out_refund_no;
        //总金额
        this.total_fee = total_fee;
        //退款金额
        this.refund_fee = refund_fee;
        //操作员
        this.op_user_id = op_user_id;
        this.sign_agentno = "10100000284";
    }

    public PayRequest(String service, String mch_id, Order order) {
        //接口类型
        this.service = service;
        //商户号
        this.mch_id = mch_id;
        //商户订单号
        this.out_trade_no = order.getRefOrderId();
        this.out_refund_no = order.getId();
        this.sign_agentno = "10100000284";
    }

    public PayRequest(String bill_date,String service,String mch_id,String bill_type) {
        this.bill_date = bill_date;
        this.service = service;
        this.mch_id = mch_id;
        this.bill_type = bill_type;

    }

    //实体转化 xml
    public String toXML() {
        XStream xstream = XStreamInitializer.getInstance();
        xstream.processAnnotations(this.getClass());
        return xstream.toXML(this);
    }

    //设置sign
    //直接使用威福通dome
    public void setUpSign(Map<String, Object> map, String key) {
        Map<String, String> params = SignUtils.paraFilter(map);
       key = "h92Tz0wF6QX66hR4pM7VVdXD4NNS3cSO";
        if (StringUtils.isNotBlank(key)) {
            sign_type = "MD5";
            params.put("sign_type", "MD5");
        } else {
            sign_type = "RSA_1_256";
            params.put("sign_type", "RSA_1_256");
        }
        StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
        SignUtils.buildPayParams(buf, params, false);
        String preStr = buf.toString();
        System.out.println(preStr);
        log.debug("The content to be signed is:{}", preStr);
        this.sign = SignUtil.getSign(sign_type, preStr, key).toUpperCase();
    }


}
